#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "InComPrint.h"

#define DEF_TAG             "Wtd"

#define WATCHDOG_FILE_PATH "/dev/watchdog"
#define WATCHDOG_IOCTL_BASE 'W'
#define WDIOC_KEEPALIVE     _IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define WDIOC_SETTIMEOUT    _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT    _IOR(WATCHDOG_IOCTL_BASE, 7, int)

static int g_ChipSdk_wdt_fd = -1; /* device fd define */
static int g_ChipSdk_wdt_feed_timeout = 0; /* watch dog feed time define */

/**
 * ak_drv_wdt_open - open watch dog and watch dog start work.
 * @feed_timeout: [in] second, [1, 357]
 * return: 0 - success; otherwise error code;
 * note:
 */
int ak_drv_wdt_open(unsigned int feed_timeout)
{
    /* arguments check */
    if (g_ChipSdk_wdt_fd >= 0)
    {
        PRT_WARN(DEF_TAG,"watch dog have been opened.\n");
        return -EBUSY;
    }

    /* feed time should > 0 */
    if (feed_timeout < 1)
    {
        PRT_ERR(DEF_TAG,"invalid arg.\n");
        return -EINVAL;
    }

    /* open watch dog device */
    g_ChipSdk_wdt_fd = open(WATCHDOG_FILE_PATH, O_RDONLY);
    if (g_ChipSdk_wdt_fd < 0)
    {
        PRT_ERR(DEF_TAG,"open watch dog  fail.\n");
        return -EACCES;
    }

    /*
     * set timeout
     * set close-on-exec flag
     */
    g_ChipSdk_wdt_feed_timeout = feed_timeout;

    if (ioctl(g_ChipSdk_wdt_fd, WDIOC_SETTIMEOUT, &g_ChipSdk_wdt_feed_timeout))
    {
        ioctl(g_ChipSdk_wdt_fd, WDIOC_GETTIMEOUT, &g_ChipSdk_wdt_feed_timeout);
        PRT_WARN(DEF_TAG,"set timeout fail, use value %d.\n", g_ChipSdk_wdt_feed_timeout);
    }

    return 0;
}

/**
 * ak_drv_wdt_feed - feed watch dog.
 * return:0 - success; otherwise error code;
 */
int ak_drv_wdt_feed(void)
{
    /** not open watch dog **/
    if(g_ChipSdk_wdt_fd < 0)
    {
        PRT_ERR(DEF_TAG,"watch dog not opened.\n");
        return -EACCES;
    }

    if (ioctl(g_ChipSdk_wdt_fd, WDIOC_KEEPALIVE, &g_ChipSdk_wdt_feed_timeout)){
        PRT_ERR(DEF_TAG,"feed fail.\n");
        return -EIO;
    }

    return 0;
}

/**
 * ak_drv_wdt_close - close watch dog.
 * return:0 - success; otherwise error code;
 */
int ak_drv_wdt_close(void)
{
    if(g_ChipSdk_wdt_fd < 0)
    {
        PRT_ERR(DEF_TAG,"watch dog not opened.\n");
        return -EACCES;
    }

    /*
     * set timeout -1 is to close watch dog,
     * its difference with close device.
     * if close device directly, system will reboot
     */
    g_ChipSdk_wdt_feed_timeout = -1;
    /*
     * before we close watch dog,
     * set watch dog alive .
     */
    if(ioctl(g_ChipSdk_wdt_fd, WDIOC_SETTIMEOUT, &g_ChipSdk_wdt_feed_timeout) < 0)
    {
        PRT_ERR(DEF_TAG,"ioctl fail.\n");
        return -EIO;
    }

    /* close device */
    if(close(g_ChipSdk_wdt_fd) < 0)
    {
        PRT_ERR(DEF_TAG,"close watch_dog fail.\n");
        return -EIO;
    }
    g_ChipSdk_wdt_fd = -1;

    return 0;
}


int main(void)
{
    PRT_INFO(DEF_TAG,"start watchdog now\n");
    /* dog hungry time is 5. */
    ak_drv_wdt_open(5);

    while(1)
    {
        //printf("feed watchdog now\n");
        ak_drv_wdt_feed();
        sleep(2);
    }

    /* close watch dog */
    ak_drv_wdt_close();

    return 0;
}

